package com.pansoft.openplanet.db;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;

import com.efounder.constant.EnvironmentVariable;
import com.pansoft.openplanet.bean.Account;
import com.pansoft.openplanet.bean.CardBean;
import com.pansoft.openplanet.blockchain.util.StringUtils;
import com.pansoft.openplanet.constant.IPAssetsConstant;
import com.pansoft.openplanet.util.EosNetParamUtil;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.efounder.frame.utils.Constants.CHAT_USER_ID;

/**
 * Created by YQS on 2018/3/27.
 */

public class AccountDao {

    private Context context;
    private SQLiteDatabase db;
    private static final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    public AccountDao(Context context) {
        this.context = context;
        db = WalletDbHelper.getInstance(context).getDb();
    }

    public void closeDb() {
        if (db != null) {
            db.close();
        }
    }

    public long insertOrReplace(Account account) {
        ContentValues values = getContentValue(account);
        return this.db.insertWithOnConflict("account1", null, values,
                SQLiteDatabase.CONFLICT_REPLACE);
    }

    public long update(Account account) {
        ContentValues values = getContentValue(account);
        return this.db.update("account1", values,
                "address=? and im_userid =?", new String[]{values.getAsString("address"), values.getAsString("im_userid")});
    }

    /**
     * 更新eos账户主账户名
     * @param oldAccountName old
     * @param newAccountName new
     */
    public void updateEosAccountName(String oldAccountName, String newAccountName) {
        String sql = "update account1 set address=? where address=?";
        this.db.execSQL(sql, new Object[]{newAccountName, oldAccountName});
    }

    /**
     * 删除一个账户
     *
     * @param address
     * @return
     */
    public long delete(String address) {

        this.db.delete("account1", "address =? and im_userid =?",
                new String[]{address, EnvironmentVariable.getProperty(CHAT_USER_ID, "")});
        return this.db.delete("account1", "address =? and im_userid =?",
                new String[]{address.toLowerCase(), EnvironmentVariable.getProperty(CHAT_USER_ID, "")});
    }

    /**
     * 删除主账户
     *
     * @return
     */
    public long deleteMainAccount() {
        return this.db.delete("account1", " is_master =? and im_userid=?",
                new String[]{1 + "", EnvironmentVariable.getProperty(CHAT_USER_ID, "")});
    }

    //删除当前用户的主账户以及子账户
    public long deleteByCurentImuserId() {

        return this.db.delete("account1", " im_userid =?",
                new String[]{EnvironmentVariable.getProperty(CHAT_USER_ID, "")});
    }

    //删除所有账户
    public long deleteAllAccount() {

        return this.db.delete("account1", null,
                new String[]{});
    }

    /**
     * 根据地址获取账户
     *
     * @param address
     * @return
     */
    public Account getAccount(String address) {
        String sql = "select * from account1 where address =? and im_userid=? ";
        List<Account> list = query(sql, new String[]{address,
                EnvironmentVariable.getProperty(CHAT_USER_ID, "")});
        if (list.size() == 0) {
            list = query(sql, new String[]{address.toLowerCase(),
                    EnvironmentVariable.getProperty(CHAT_USER_ID, "")});
        }
        return list.size() == 0 ? null : list.get(0);
    }

    /**
     * 根据公钥获取账号信息
     * @param pubKey 公钥
     * @return
     */
    public Account getAccountByPubKey(String pubKey) {
        String sql = "select * from account1 where public_key =? and im_userid=? ";
        List<Account> list = query(sql, new String[]{pubKey,
                EnvironmentVariable.getProperty(CHAT_USER_ID, "")});
        if (list.size() == 0) {
            list = query(sql, new String[]{pubKey.toLowerCase(),
                    EnvironmentVariable.getProperty(CHAT_USER_ID, "")});
        }
        return list.size() == 0 ? null : list.get(0);
    }

    /**
     * 根据active公钥查询eos账户
     *
     * @param activePublicKey
     * @return
     */
    public Account getEosAccountByActivePublicKey(String activePublicKey) {
        String sql = "select * from account1 where eos_active_pubkey =? and im_userid=?";
        List<Account> list = query(sql, new String[]{activePublicKey,
                EnvironmentVariable.getProperty(CHAT_USER_ID, "")});
        return list.size() == 0 ? null : list.get(0);
    }

    //获取主账号信息（必须是可用的 enable 表示已激活）
    public Account getMainAccount() {
        String sql = "select * from account1 where is_master =? and im_userid=? and enable=?";
        List<Account> list = query(sql, new String[]{1 + "",
                EnvironmentVariable.getProperty(CHAT_USER_ID, ""), 1 + ""});
        return list.size() == 0 ? null : list.get(0);
    }

    //获取主账号信息（不管是否可用）
    public Account getMainAccountInDb() {
        String sql = "select * from account1 where is_master =? and im_userid=? ";
        List<Account> list = query(sql, new String[]{1 + "",
                EnvironmentVariable.getProperty(CHAT_USER_ID, "")});
        return list.size() == 0 ? null : list.get(0);
    }

    /**
     * 获取所有的子钱包
     *
     * @param blockChainEnum
     * @return
     */
    public List<Account> getAllChildAccount(IPAssetsConstant.ChainEnum blockChainEnum) {
        return getAllChildAccount(blockChainEnum.chainName);
    }

    /**
     * 获取所有激活的eos账户
     * @param blockChainEnum
     * @return
     */
    public List<Account> getAllActivatedEosAccount(IPAssetsConstant.ChainEnum  blockChainEnum) {
        String sql = "select * from account1 where block_chain_name =? and im_userid=? and enable=? " +
                "and eos_is_activate=?";
        List<Account> list = query(sql, new String[]{blockChainEnum.chainName,
                EnvironmentVariable.getProperty(CHAT_USER_ID, ""), "1", "1"});
        return list;
    }

    /**
     * 获取所有的子钱包
     *
     * @param type（ETH BTC）
     * @return
     */
    public List<Account> getAllChildAccount(String type) {
//        String sql = "select * from account1 where block_chain_name =? and im_userid=? and enable=? and is_master =?";
//        List<Account> list = query(sql, new String[]{type,
//                EnvironmentVariable.getProperty(CHAT_USER_ID, ""), "1", "0"});
        String sql = "select * from account1 where block_chain_name =? and im_userid=? and enable=? ";
        List<Account> list = query(sql, new String[]{type,
                EnvironmentVariable.getProperty(CHAT_USER_ID, ""), "1"});
        return list;
    }

    /**
     * 获取所有的账户（钱包）
     *
     * @param blockChainEnum
     * @return
     */
    public List<Account> getAllAccount(IPAssetsConstant.ChainEnum blockChainEnum) {
        String sql = "select * from account1 where block_chain_name =? and im_userid=? and enable=?";
        List<Account> list = query(sql, new String[]{blockChainEnum.chainName,
                EnvironmentVariable.getProperty(CHAT_USER_ID, ""), 1 + ""});
        return list;
    }


    /**
     * 更改当前显示的账户
     *
     * @param blockChainEnum
     * @param accountAddress 要显示的账户地址
     * @return
     */
    public void updateCurrentShowAccount(IPAssetsConstant.ChainEnum blockChainEnum, String accountAddress) {
        //第一步，将所有的 blockChainEnum 的更新为 不是当前显示
        String sql = "update  account1 set is_current_show =? where block_chain_name =? and im_userid=?";
        db.execSQL(sql, new String[]{0 + "", blockChainEnum.chainName, EnvironmentVariable.getProperty(CHAT_USER_ID, "")});
        //标记当前地址的账户为显示
        String sql1 = "update  account1 set is_current_show =? where block_chain_name =? and im_userid=? and address=?";
        db.execSQL(sql1, new String[]{1 + "", blockChainEnum.chainName,
                EnvironmentVariable.getProperty(CHAT_USER_ID, ""), accountAddress});
    }

    /**
     * 获取当前显示的账户
     *
     * @param blockChainEnum
     * @param
     * @return
     */
    public Account getCurrentShowAccount(IPAssetsConstant.ChainEnum blockChainEnum) {
//        String sql = "select * from account1 where block_chain_name =? and im_userid=? and is_current_show=? and is_master =?";
//        List<Account> list = query(sql, new String[]{blockChainEnum.chainName,
//                EnvironmentVariable.getProperty(CHAT_USER_ID, ""), "1", "0"});
        String sql = "select * from account1 where block_chain_name =? and im_userid=? and is_current_show=? ";
        List<Account> list = query(sql, new String[]{blockChainEnum.chainName,
                EnvironmentVariable.getProperty(CHAT_USER_ID, ""), "1"});
        return list.size() == 0 ? null : list.get(0);
    }

    /**
     * 获取当前显示的账户(根据mode)
     *
     * @param chainId
     * @param
     * @return
     */
    public Account getCurrentShowAccount(int chainId) {
        if (chainId == IPAssetsConstant.CHAIN_ID_ETH) {
            return getCurrentShowAccount(IPAssetsConstant.ChainEnum.ETH);
        } else if (chainId == IPAssetsConstant.CHAIN_ID_ETE) {
            return getCurrentShowAccount(IPAssetsConstant.ChainEnum.ETE);
        } else if (chainId == IPAssetsConstant.CHAIN_ID_BTC) {
            return getCurrentShowAccount(IPAssetsConstant.ChainEnum.BTC);
        } else if (chainId == EosNetParamUtil.getEosChainId()) {
            return getCurrentShowAccount(EosNetParamUtil.getEosChainEnum());
        } else {
            throw new RuntimeException("mode参数错误");
        }
    }

    /**
     * 根据冷钱包的地址，获取卡片数据库的信息
     * @param address 冷钱包地址
     * @return cardBean
     */
    public CardBean getColdWalletCardBean(String address) {
        Account account = getAccount(address);
        if (account == null) {
            return null;
        }
        String uid = account.getColdWalletCardUid();
        if (uid == null || "".equals(uid)) {
            return null;
        }
        return new CardDao(context).getCardBean(uid);
    }

    public List<Account> getAllChildAccount() {
        String sql = "select * from account1 where im_userid =? and enable=?";
        List<Account> list = query(sql, new String[]{EnvironmentVariable.getProperty(CHAT_USER_ID, ""), 1 + ""});
        return list;
    }

    private List<Account> query(String sql) {
        return query(sql, null);
    }

    private List<Account> query(String sql, String[] selectionArgs) {
        List<Account> list = new ArrayList<Account>();
        Cursor cursor = this.db.rawQuery(sql, selectionArgs);
        while (cursor.moveToNext()) {
            Account account = new Account();
            account.setAddress(cursor.getString(cursor.getColumnIndex("address")));
            String name = cursor.getString(cursor.getColumnIndex("account_name"));
            String avatar = cursor.getString(cursor.getColumnIndex("account_avatar"));
            String time = cursor.getString(cursor.getColumnIndex("create_time"));
            String filename = cursor.getString(cursor.getColumnIndex("account_filename"));
            String imUserId = cursor.getString(cursor.getColumnIndex("im_userid"));

            int is_master = cursor.getInt(cursor.getColumnIndex("is_master"));
            int isCurrentShow = cursor.getInt(cursor.getColumnIndex("is_current_show"));
            int account_type = cursor.getInt(cursor.getColumnIndex("account_type"));
            String blockChainName = cursor.getString(cursor.getColumnIndex("block_chain_name"));
            String mainAccountAddress = cursor.getString(cursor.getColumnIndex("main_account_address"));
            String secretPrivatekey = cursor.getString(cursor.getColumnIndex("secret_private_key"));
            String publicKey = cursor.getString(cursor.getColumnIndex("public_key"));
            String secretMnemonicKey = cursor.getString(cursor.getColumnIndex("secret_mnemonic_key"));
            String eosActivePubKey = cursor.getString(cursor.getColumnIndex("eos_active_pubkey"));
            String eosActivePriKey = cursor.getString(cursor.getColumnIndex("eos_active_prikey"));
            int enable = cursor.getInt(cursor.getColumnIndex("enable"));

            String hdBtcXpub = cursor.getString(cursor.getColumnIndex("hd_btc_x_pub"));
            String hdBtcCurrentChildAddress = cursor.getString(cursor.getColumnIndex("hd_btc_current_child_address"));
            String hdBtcMaxChildIndex = cursor.getString(cursor.getColumnIndex("hd_btc_child_path_max_index"));


            if (name == null || "".equals(name)) {
                account.setAcccountName("账户");
            } else {
                account.setAcccountName(name);
            }
            if (avatar == null || "".equals(avatar)) {
                account.setAccountAvatar("");
            } else {
                account.setAccountAvatar(avatar);
            }
            if (time == null || "".equals(time)) {
                account.setCreateTime(null);
            }
            account.setFileName(filename);
            account.setImUserId(imUserId);

            account.setMaster(is_master == 1 ? true : false);
            account.setCurrentShow(isCurrentShow == 1 ? true : false);
            account.setAccountType(account_type);
            account.setBlockChainName(blockChainName);
            account.setMainAccoutAddress(mainAccountAddress);
            account.setSecretPrivateKey(secretPrivatekey);
            account.setPublicKey(publicKey);
            account.setEnable(enable == 1 ? true : false);
            account.setSecretMnemonic(secretMnemonicKey);
            account.setEosActivePubKey(eosActivePubKey);
            account.setEosActivePriKey(eosActivePriKey);
            account.setActivate(cursor.getInt(cursor.getColumnIndex("eos_is_activate")) == 1 ? true : false);
            account.setEosTempName(cursor.getString(cursor.getColumnIndex("eos_temp_name")));
            account.setEosAccountNames(cursor.getString(cursor.getColumnIndex("eos_account_names")));
            account.setColdWalletCardUid(cursor.getString(cursor.getColumnIndex("cold_wallet_card_id")));
            account.setHdBtcXpub(StringUtils.isEmpty(hdBtcXpub) ? "" : hdBtcXpub);
            account.setHdBtcCurrentChildAddress(StringUtils.isEmpty(hdBtcCurrentChildAddress) ? "" : hdBtcCurrentChildAddress);
            account.setHdBtcMaxChildIndex(StringUtils.isEmpty(hdBtcMaxChildIndex) ? "" : hdBtcMaxChildIndex);
            list.add(account);
        }
        cursor.close();
        return list;
    }

    private ContentValues getContentValue(Account account) {
        ContentValues values = new ContentValues();
        //处理钱包地址
        if (IPAssetsConstant.ChainEnum.ETH.chainName.equals(account.getBlockChainName())) {
            //eth 钱包地址转成小写
            values.put("address", account.getAddress().toLowerCase());
        } else {
            values.put("address", account.getAddress());
        }
        //处理钱包名称
        if (TextUtils.isEmpty(account.getAcccountName())) {
            values.put("account_name", account.getBlockChainName() + "-Wallet");
        } else {
            values.put("account_name", account.getAcccountName());
        }

        values.put("account_avatar", account.getAccountAvatar());
        values.put("account_filename", account.getFileName() == null ? "" : account.getFileName());
        values.put("create_time", account.getCreateTime() == null ? sf.format(new Date()) : account.getCreateTime());
        values.put("im_userid", account.getImUserId() == null ? EnvironmentVariable.getProperty(CHAT_USER_ID) : account.getImUserId());
        values.put("is_master", account.isMaster() ? 1 : 0);
        values.put("is_current_show", account.isCurrentShow() ? 1 : 0);
        values.put("account_type", account.getAccountType());
        values.put("block_chain_name", account.getBlockChainName() == null ? "" : account.getBlockChainName());
        values.put("main_account_address", account.getMainAccoutAddress() == null ? "" : account.getMainAccoutAddress());
        values.put("secret_private_key", account.getSecretPrivateKey() == null ? "" : account.getSecretPrivateKey());
        values.put("enable", account.isEnable() == true ? 1 : 0);
        values.put("public_key", account.getPublicKey() == null ? "" : account.getPublicKey());
        values.put("secret_mnemonic_key", account.getSecretMnemonic() == null ? "" : account.getSecretMnemonic());

        values.put("eos_active_pubkey", account.getEosActivePubKey() == null ? "" : account.getEosActivePubKey());
        values.put("eos_active_prikey", account.getEosActivePriKey() == null ? "" : account.getEosActivePriKey());
        values.put("eos_is_activate", account.isActivate() == true ? 1 : 0);
        values.put("eos_account_names", account.getEosAccountNames() == null ? "" : account.getEosAccountNames());
        values.put("eos_temp_name", account.getEosTempName() == null ? "" : account.getEosTempName());
        values.put("cold_wallet_card_id", account.getColdWalletCardUid() == null ? "" : account.getColdWalletCardUid());
        values.put("hd_btc_x_pub", account.getHdBtcXpub() == null ? "" : account.getHdBtcXpub());
        values.put("hd_btc_current_child_address", account.getHdBtcCurrentChildAddress() == null ? "" : account.getHdBtcCurrentChildAddress());
        values.put("hd_btc_child_path_max_index", account.getHdBtcMaxChildIndex() == null ? "" : account.getHdBtcMaxChildIndex());
        return values;
    }
}




